home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
PROGRAMM
/
PASCAL
/
2856.ZIP
/
KEYTREE.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-05-11
|
53KB
|
1,720 lines
unit KeyTree;
{$M 4096,0,655360}
{ FEBRUARY 1991 version 3
*****************************************************************************
* *
* KeyTree Toolbox *
* *
* Copyright 1991 by Rewse Consultants Limited *
* *
* The KeyTree Toolbox is issued as shareware. In case you are unaware of *
* how the shareware system works, it is NOT 'free' software. *
* No initial charge is made for the software, so that you can try it out *
* without obligation. However, if you continue to use the software (and in *
* the case of the KeyTree Toolbox, use programs created using it), *
* then you are required to pay a registration fee. To register your use of *
* the KeyTree Toolbox, we ask you to pay a miserly £30 (UK Pounds), a mere *
* fraction of the cost that you are saving in time and effort. Please send *
* your registration fee to : *
* *
* Rewse Consultants Limited *
* 44, Horseshoe Road, Pangbourne, Reading, Berkshire RG8 7JL, UK *
****************************************************************************}
interface
uses crt,dos;
type arrayn = array[0..1] of integer;
arrayp = ^arrayn;
Chars = array[0..1] of char;
charp = ^Chars;
const ktRUNCH : char = #0;
ktRUNSC : integer = 0;
var ktSCAN,ktERRNO,ktFKEY : integer;
ktCHAR : char;
ktINDEXED : Boolean;
function ktCreate(name : string; chain, indexct : integer; var keys )
: Boolean;
function ktOpen(name : string; mode, indexno : integer) : integer;
function ktChangeIndex(f, indexno : integer) : Boolean;
function ktFlush(f : integer) : Boolean;
function ktClose(f : integer) : Boolean;
function ktAdd(f : integer; var data; size : integer) : Boolean;
function ktAddPhys(f : integer; var data; size : integer) : Boolean;
function ktRead(f : integer; var data; key : string) : integer;
function ktReadAfter(f : integer; var data; key : string) : integer;
function ktReadBefore(f : integer; var data; key : string) : integer;
function ktLength(f : integer; key : string) : integer;
function ktNext(f : integer; var data) : integer;
function ktPrev(f : integer; var data) : integer;
function ktNextPhys(f : integer; var data) : integer;
function ktPrevPhys(f : integer; var data) : integer;
function ktDelete(f : integer; var data) : Boolean;
function ktUndelete(f : integer; var data) : Boolean;
function ktRewrite(f : integer; var data; size : integer) : Boolean;
procedure ktGetChar;
procedure ktGetPress;
function ktGetStr(var data; maxlen : integer) : integer;
function ktGetKey(f : integer; var data,key) : integer;
function ktReadAll(f : integer; var data; key : string) : integer;
function ktNextAll(f : integer; var data) : integer;
function ktPrevAll(f : integer; var data) : integer;
function ktAddChain(f : integer; var data; size : integer) : Boolean;
function ktNextChain(f : integer; var data) : integer;
function ktPrevChain(f : integer; var data) : integer;
function ktStart(f : integer; var data) : integer;
function ktEnd(f : integer; var data) : integer;
function ktStartPhys(f : integer; var data) : integer;
function ktEndPhys(f : integer; var data) : integer;
function ktLock(f : integer) : Boolean;
function ktUnlock(f : integer) : Boolean;
function ktLocked(f : integer; key : string) : Boolean;
function ktSize(f : integer) : longint;
function ktRecords(f,typ : integer) : longint;
function ktMaxRead(f,max : integer) : integer;
procedure KtBuildKey(f : integer; var d ;f1,f2 : string);
implementation
uses funckey;
type
Bytes = array[0..MaxInt] of byte;
kt_rec = record dup,inxct,curinx,inx_entry,access,ksz : integer;
fd : file;
curtyp,maxkey,ixdes,ixlen,kt,minsiz,hks : integer;
chain : array[0..1] of longint;
inx_pos,base,recptr,nexrec,fsize : longint;
BaseEntry,start : longint;
status : byte;
filename : string[15];
keys : arrayp;
del,maxread : integer;
end;
bb_ptr = ^Bytes;
strptr = ^string;
kt_ptr = ^kt_rec;
kt_ptr_ptr = array[0..1] of kt_ptr;
kt_list = ^kt_ptr_ptr;
ix_dets = record ix : longint;
en,x : integer;
end;
const kt_inx_size : array[0..3] of integer = (30,13,40,99);
kt_filect : integer = 0;
kt_function : Boolean = False;
ext_fil : string[5] = '.fil';
my_list : kt_list = nil;
cur_ind_ind : integer = 1000;
cur_ind_fd : integer = 1000;
cur_ind_pos : longint = 1000;
var KT : kt_ptr;
kt_alter : array[0..10] of ix_dets;
kt_tmplen : array[0..1] of integer;
kt_inx_char : longint;
kt_inx : array[0..99] of longint;
kt_FORWARD,ktCT : integer;
old_length : array[0..1] of integer;
oldix : array[0..10] of ix_dets;
record_moved : Boolean;
kt_found : Boolean;
my_k,my_x,my_y : integer;
oldk,newk : pointer;
{$I-}
procedure kt_wrt_data(var ptr ; len : integer);
var b : integer;
begin BlockWrite(KT^.fd,Chars(ptr),word(len));
b := IOresult;
end;
procedure kt_read_data(var ptr ; len : integer);
var b : integer;
begin BlockRead(KT^.fd,Chars(ptr),len);
b := IOresult;
end;
procedure kt_seek(offs : longint);
var b : integer;
begin seek(KT^.fd,offs);
b := IOresult;
end;
procedure kt_wrt_status;
begin kt_seek(KT^.recptr);
kt_wrt_data(KT^.status,1);
end;
procedure kt_wrt_elem(var recpt; y : integer);
var x : integer;
begin kt_wrt_status;
x := 0;
if (KT^.dup <> 0) then kt_wrt_data(KT^.chain[0],KT^.dup);
kt_wrt_data(y,2);
kt_wrt_data(x,2);
kt_wrt_data(recpt,y);
x := y + KT^.dup + 7;
kt_wrt_data(x,2);
Inc(KT^.fsize,x);
end;
function kt_FileOpen(fno : integer) : Boolean;
begin if (fno > 0) then
begin Dec(fno);
if (fno < kt_filect) then
begin KT := my_list^[fno];
if (KT <> nil) then
begin ktERRNO := 0;
kt_FileOpen := True;
exit;
end;
end;
end;
ktERRNO := 9;
kt_FileOpen := False;
end;
function kt_FileReady(fno : integer) : Boolean;
var x : integer;
begin kt_FileReady := True;
if kt_FileOpen(fno) then
begin x := KT^.status and $80;
if x <> 0 then ktERRNO := 28
else begin if (KT^.recptr > 0) then exit;
ktERRNO := 20;
end;
end;
kt_FileReady := False;
end;
function kt_OKtowrite : Boolean;
begin kt_OKtowrite := True;
if (KT^.access <> 0) then exit;
ktERRNO := 12;
kt_OKtowrite := False;
end;
function kt_locked(fno : integer) : Boolean;
var x : integer;
begin kt_locked := True;
if not kt_FileReady(fno) then exit;
if not kt_OKtowrite then exit;
x := KT^.status and 1;
if x <> 0 then begin ktERRNO := 22;
exit;
end;
kt_locked := False;
end;
function kt_inx_key(keychar : char) : integer;
var z : byte; x : char;
begin x := keychar;
z := Ord(x);
if z <> 0 then case KT^.curtyp of
0 : begin if (x = ' ') then z := 2
else begin if (x >= 'a') and (x <= 'z') then Dec(z,94)
else begin if (x >= 'A') and (x <= 'Z')
then Dec(z,62)
else z := 1;
end;
end;
end;
1 : begin if (z < 47) or (z > 57) then z := 1
else Dec(z,46);
end;
2 : begin if (x = ' ') then z := 2
else begin if (x >= 'a') and (x <= 'z') then Dec(z,84)
else begin
if (x >= 'A') and (x <= 'Z') then Dec(z,52)
else begin Dec(z,45);
if (z < 3) or (z > 12) then z := 1;
end;
end;
end;
end;
3 : begin if (z < 31) or (z > 127) then z := 1
else Dec(z,30);
end;
end;
KT^.inx_entry := z + 1;
kt_inx_key := z + 1;
end;
procedure kt_setupkey(var key, recpt);
var x,y,z,L,S,b,c : integer;
begin for x := 1 to KT^.maxkey do Chars(key)[x] := #0;
y := KT^.ixdes;
z := 1;
c := KT^.keys^[3*(KT^.curinx) + 2];
for x := 1 to c
do begin L := KT^.keys^[y];
Inc(y);
S := KT^.keys^[y];
Inc(y);
while (Bytes(recpt)[s] <> 0) and (L > 0) do
begin Chars(key)[z] := Chars(recpt)[S];
Inc(z);
Inc(S);
Dec(L);
end;
if (x < c) and (L > 0) then Inc(z);
end;
Bytes(key)[0] := z - 1;
end;
procedure kt_readkey(var ptr);
var trec : charp; x : word;
begin
kt_seek(kt_inx_char);
kt_read_data(KT^.status,1);
if (KT^.dup <> 0) then kt_seek(kt_inx_char + KT^.dup + 1);
kt_read_data(kt_tmplen[0],2);
kt_read_data(x,2);
if kt_tmplen[0] > KT^.maxkey then x := kt_tmplen[0]
else x := KT^.maxkey + 1;
GetMem(trec,x);
if (trec = nil) then ktERRNO := 7
else begin FillChar(trec^,x,#0);
kt_read_data(trec^,kt_tmplen[0]);
kt_setupkey(ptr,trec^);
FreeMem(trec,x);
end;
end;
procedure kt_setname(var ptr1,ptr2);
var x,y : integer;
begin
x := 1;
y := Bytes(ptr1)[0];
move(Bytes(ptr1)[0], Bytes(ptr2)[0], y + 1);
while (x <= y) and (Chars(ptr1)[x] <> '.') do Inc(x);
if (x > y) then
begin Move(ext_fil[1],Bytes(ptr2)[x],4);
Bytes(ptr2)[0] := x + 3;
end;
end;
function kt_read_elem(var recpt) : integer;
var x,a : integer;
begin
kt_read_elem := 0;
ktINDEXED := ((KT^.status and 2) = 0);
if (KT^.dup <> 0) then kt_read_data(KT^.chain[0],KT^.dup);
kt_read_data(x,2);
kt_read_data(a,2);
if (x > 0) then
begin KT^.nexrec := KT^.recptr + x + a + KT^.dup + 7;
kt_read_elem := x;
if (KT^.maxread > 0) and (x > KT^.maxread) then
x := KT^.maxread;
kt_read_data(recpt,x);
end
else ktERRNO := 18;
end;
function kt_read_indexed(var recpt) : integer;
begin kt_seek(KT^.recptr);
kt_read_data(KT^.status,1);
kt_read_indexed := kt_read_elem(recpt);
end;
procedure kt_next_index(y : integer);
var x,z : integer;
begin
KT^.curinx := y;
KT^.curtyp := KT^.keys^[3*y + 1];
KT^.maxkey := 0;
z := 3*KT^.inxct;
if y > 0 then for x := 0 to y - 1 do Inc(z,2*KT^.keys^[3*x + 2]);
KT^.ixdes := z;
for x := 1 to KT^.keys^[3*y + 2] do
begin Inc(KT^.maxkey,KT^.keys^[z]);
Inc(z,2);
end;
end;
procedure kt_read_index;
begin
if (KT^.kt <> cur_ind_fd) or (KT^.inx_pos <> cur_ind_pos) or
(cur_ind_ind <> KT^.curinx) then
begin kt_seek(-KT^.inx_pos + 1);
kt_read_data(kt_inx,kt_inx_size[KT^.curtyp]*SizeOf(longint));
cur_ind_ind := KT^.curinx;
cur_ind_fd := KT^.kt;
cur_ind_pos := KT^.inx_pos;
end;
end;
procedure kt_wrt_index;
var b : integer; a : array[0..1] of byte;
begin
kt_seek(-KT^.inx_pos);
a[0] := byte('0') + KT^.curinx;
kt_wrt_data(a,1);
b := kt_inx_size[KT^.curtyp]*SizeOf(longint);
kt_wrt_data(kt_inx,b);
if KT^.fsize = -KT^.inx_pos then begin Inc(b,3);
kt_wrt_data(b,2);
Inc(KT^.fsize,b);
end;
cur_ind_ind := KT^.curinx;
cur_ind_fd := KT^.kt;
cur_ind_pos := KT^.inx_pos;
end;
procedure kt_zero_index(k : integer);
var L,Q : longint; x,y,b : integer;
begin
kt_inx[KT^.inx_entry] := 0;
if kt_inx[0] <> 0 then
begin y := 0;
b := 0;
Q := 0;
for x := 1 to kt_inx_size[KT^.curtyp] - 1 do
begin if kt_inx[x] <> 0 then
begin Inc(y);
if y > 1 then x := kt_inx_size[KT^.curtyp] - 1
else begin Q := kt_inx[x];
if x < KT^.inx_entry then b := 1
else b := 2;
end;
end;
end;
if (y < 2) and (Q >= 0) then
begin while (y < 2) and (kt_inx[0] <> 0) do
begin L := KT^.inx_pos;
KT^.inx_pos := kt_inx[0];
kt_read_index;
KT^.inx_entry := 1;
while (L <> kt_inx[KT^.inx_entry]) do
Inc(KT^.inx_entry);
if (KT^.BaseEntry <> 0) and (L = KT^.base) then
begin KT^.base := KT^.inx_pos;
KT^.BaseEntry := KT^.inx_entry;
end;
kt_inx[KT^.inx_entry] := Q;
y := 0;
for x := 1 to kt_inx_size[KT^.curtyp] - 1 do
begin if kt_inx[x] <> 0 then Inc(y);
if y > 1 then x := kt_inx_size[KT^.curtyp] - 1
end;
end;
if k = KT^.curinx then KT^.del := b;
end;
end;
kt_wrt_index;
end;
procedure set_values(x,z : integer);
begin
kt_alter[KT^.curinx].ix := KT^.inx_pos;
kt_alter[KT^.curinx].x := x;
kt_alter[KT^.curinx].en := z;
end;
function kt_lookup(var key) : Boolean;
var x,y,z,k : integer;
begin
KT^.inx_pos := -KT^.keys^[3*KT^.curinx];
y := KT^.maxkey;
if y > Bytes(key)[0] then y := Bytes(key)[0];
kt_lookup := False;
for x := 1 to y + 1 do
begin kt_read_index;
if x = y + 1 then z := kt_inx_key(#0)
else z := kt_inx_key(Chars(key)[x]);
if kt_inx[z] = 0 then begin set_values(x,z);
exit;
end;
kt_inx_char := kt_inx[z];
if kt_inx_char > 0 then begin KT^.recptr := kt_inx_char;
kt_lookup := True;
set_values(x,z);
exit;
end;
KT^.inx_pos := kt_inx_char;
end;
end;
procedure kt_record_lookup(var recpt);
var temk : pointer; x : Boolean; f : integer;
begin f := KT^.maxkey+1;
GetMem(temk,f);
if (temk <> nil) then begin kt_setupkey(temk^,recpt);
x := kt_lookup(temk^);
FreeMem(temk,f);
end;
end;
function kt_keysmatch(var new,old) : integer;
var x,y,z,f,q : integer; a,b : char;
begin
kt_keysmatch := 0;
f := 0;
if Ord(chars(new)[0]) > KT^.maxkey then q := KT^.maxkey
else q := Ord(chars(new)[0]);
for x := 1 to q do
begin if f >= Ord(chars(old)[0]) then
begin kt_keysmatch := 1;
exit;
end;
Inc(f);
a := Chars(new)[x];
b := Chars(old)[x];
if a <> b then begin z := KT^.inx_entry;
y := kt_inx_key(a) - kt_inx_key(b);
KT^.inx_entry := z;
if y <> 0 then
begin kt_keysmatch := y;
exit;
end;
end;
end;
if f < Ord(chars(old)[0]) then kt_keysmatch := -1;
end;
function kt_exists(var key) : integer;
var z,f : integer; temk : charp; s : string;
begin
if kt_lookup(key) then
begin f := KT^.maxkey+1;
GetMem(temk,f);
if (temk <> nil) then
begin
kt_readkey(temk^);
z := kt_keysmatch(chars(key),temk^);
FreeMem(temk,f);
if z = 0 then begin kt_exists := kt_tmplen[0];
exit;
end;
end;
end;
kt_exists := 0;
end;
procedure compare_chars;
var i : integer; q : longint;
begin q := -KT^.fsize;
while True do begin my_k := kt_inx_key(Chars(oldk^)[my_y]);
my_x := kt_inx_key(Chars(newk^)[my_y]);
if my_k <> my_x then exit;
kt_inx[my_k] := q;
kt_wrt_index;
kt_inx[0] := KT^.inx_pos;
KT^.inx_pos := q;
Dec(q,kt_inx_size[KT^.curtyp]*SizeOf(longint) + 3);
for i := 1 to kt_inx_size[KT^.curtyp] do
kt_inx[i] := 0;
Inc(my_y);
end;
end;
procedure kt_update_index(var recpt; s : integer);
var L : longint; f : integer;
begin
L := KT^.recptr;
if s <> 0 then KT^.inx_pos := -KT^.keys^[3*KT^.curinx]
else KT^.inx_pos := kt_alter[KT^.curinx].ix;
f := KT^.maxkey+1;
GetMem(newk,f);
if newk = nil then begin ktERRNO := 7;
exit;
end;
FillChar(newk^,f,#0);
kt_setupkey(newk^,recpt);
kt_read_index;
if s <> 0 then
begin my_y := 1;
kt_inx_char := -1;
while kt_inx_char < 0 do
begin my_x := kt_inx_key(Chars(newk^)[my_y]);
kt_inx_char := kt_inx[my_x];
if kt_inx_char < 0 then
begin KT^.inx_pos := kt_inx_char;
kt_read_index;
Inc(my_y);
end;
end;
end
else begin my_x := kt_alter[KT^.curinx].en;
my_y := kt_alter[KT^.curinx].x;
end;
kt_inx_char := kt_inx[my_x];
if kt_inx_char <> 0 then begin GetMem(oldk,f);
if (oldk <> nil) then
begin kt_readkey(oldk^);
compare_chars;
kt_inx[my_k] := kt_inx_char;
FreeMem(oldk,f);
end;
end;
KT^.recptr := L;
kt_inx[my_x] := KT^.recptr;
KT^.inx_entry := my_x;
kt_wrt_index;
FreeMem(newk,f);
end;
function kt_OKtoadd(var recpt; err : integer) : Boolean;
var y,z,k,j,f : integer; L : longint; keypt : charp; s : string;
c : char;
begin
kt_OKtoadd := False;
k := KT^.curinx;
L := KT^.recptr;
for y := 0 to KT^.inxct - 1 do
begin kt_alter[y].ix := 0;
kt_next_index(y);
f := KT^.maxkey+1;
GetMem(keypt,f);
if keypt = nil then begin ktERRNO := 7;
exit;
end;
FillChar(keypt^,f,#0);
kt_setupkey(keypt^,recpt);
j := kt_exists(keypt^);
FreeMem(keypt,f);
if j <> 0 then begin ktERRNO := y + err;
kt_next_index(k);
KT^.recptr := L;
exit;
end;
end;
kt_next_index(k);
KT^.recptr := L;
kt_OKtoadd := True;
end;
function ktCreate(name : string; chain, indexct : integer; var keys) : Boolean;
var x,y,z,k,n,f,b : integer; zz : array[0..1] of char; t : kt_rec;
begin
ktERRNO := 13;
ktCreate := False;
if (chain <> 0) then chain := 2*SizeOf(longint);
if (indexct > 10) or (indexct <= 0) then exit;
k := 0;
y := 0;
for x := 1 to indexct do
begin if (arrayn(keys)[y] < 0) or
(arrayn(keys)[y] > 3) then exit;
if (arrayn(keys)[y + 1] < 1) then exit;
Inc(y);
while arrayn(keys)[y] >= 0 do
begin Inc(k,2);
if arrayn(keys)[y] < 1 then exit;
Inc(y);
if arrayn(keys)[y] < 0 then exit;
Inc(y);
end;
Inc(y);
end;
kt_setname(name,t.filename);
Assign(t.fd,t.filename);
Reset(t.fd,1);
if IOresult = 0 then begin Close(t.fd);
ktERRNO := 1;
exit;
end;
Rewrite(t.fd,1);
ktERRNO := 2;
if IOresult <> 0 then exit;
t.inxct := indexct;
t.dup := 19284;
if chain <> 0 then Inc(t.dup);
t.curinx := 2*(k + 3*indexct);
BlockWrite(t.fd,t.dup,6);
if IOresult <> 0 then begin Close(t.fd);
exit;
end;
f := t.curinx;
GetMem(t.keys,f);
if t.keys = nil then begin ktERRNO := 7;
Close(t.fd);
exit;
end;
n := t.curinx + 6;
z := 3*indexct;
y := 0;
for x := 0 to 3*indexct - 1 do
begin t.keys^[x] := n;
Inc(x);
Inc(n, kt_inx_size[arrayn(keys)[y]]*SizeOf(longint) + 3);
t.keys^[x] := arrayn(keys)[y];
Inc(x);
Inc(y);
t.keys^[x] := 0;
while arrayn(keys)[y] >= 0 do
begin Inc(t.keys^[x]);
t.keys^[z] := arrayn(keys)[y];
Inc(z);
Inc(y);
t.keys^[z] := arrayn(keys)[y];
Inc(z);
Inc(y);
end;
Inc(y);
end;
BlockWrite(t.fd,t.keys^,t.curinx);
if IOresult <> 0 then begin Close(t.fd);
FreeMem(t.keys,f);
exit;
end;
for x := 0 to 98 do kt_inx[x] := 0;
for x := 0 to indexct - 1 do
begin zz[0] := char(byte('0') + x);
BlockWrite(t.fd,zz,1);
if IOresult <> 0 then begin Close(t.fd);
FreeMem(t.keys,f);
exit;
end;
b := kt_inx_size[t.keys^[3*x + 1]]*SizeOf(longint);
BlockWrite(t.fd,kt_inx,b);
if IOresult <> 0 then begin Close(t.fd);
FreeMem(t.keys,f);
exit;
end;
Inc(b,3);
BlockWrite(t.fd,b,2);
if IOresult <> 0 then begin Close(t.fd);
FreeMem(t.keys,f);
exit;
end;
end;
Close(t.fd);
FreeMem(t.keys,f);
ktERRNO := 0;
ktCreate := True;
end;
procedure set_min_size;
var x,y,z,q,a : integer;
begin z := 3*KT^.inxct;
KT^.minsiz := 1;
KT^.hks := 1;
for x := 0 to KT^.inxct - 1 do
begin y := KT^.keys^[3*x + 2];
for a := 1 to y do
begin q := KT^.keys^[z] + KT^.keys^[z+1];
if KT^.minsiz < q then KT^.minsiz := q;
if KT^.keys^[z+1] > KT^.hks - 1 then
KT^.hks := KT^.keys^[z+1] + 1;
Inc(z,2);
end;
end;
end;
function ktOpen(name : string; mode, indexno : integer) : integer;
var x,y : integer; t : kt_ptr; tt : kt_list; bb : bb_ptr; c : char;
begin
ktOpen := 0;
if (indexno < 0) then begin ktERRNO := 4;
exit;
end;
ktERRNO := 0;
y := 0;
tt := my_list;
if kt_filect > 0 then
begin while (y < kt_filect) and (my_list^[y] <> nil) do Inc(y);
if y = kt_filect then
begin Inc(kt_filect);
GetMem(tt,kt_filect*SizeOf(kt_ptr));
if tt = nil then begin ktERRNO := 7;
exit;
end;
for x := 0 to y - 1 do tt^[x] := my_list^[x];
FreeMem(my_list,y*SizeOf(kt_ptr));
my_list := tt;
end;
end
else begin GetMem(my_list,SizeOf(kt_ptr));
if my_list = nil then begin ktERRNO := 7;
exit;
end;
kt_filect := 1;
end;
GetMem(my_list^[y],SizeOf(kt_rec));
KT := my_list^[y];
if KT = nil then begin ktERRNO := 7;
exit;
end;
KT^.kt := y;
kt_setname(name,KT^.filename);
Assign(KT^.fd,KT^.filename);
Reset(KT^.fd,1);
if IOresult <> 0 then begin ktERRNO := 2;
FreeMem(my_list^[y],SizeOf(kt_rec));
my_list^[y] := nil;
exit;
end
else begin
KT^.maxread := 0;
KT^.fsize := FileSize(KT^.fd);
if KT^.fsize <= 0 then ktERRNO := 6
else begin
kt_seek(0);
kt_read_data(KT^,6);
x := KT^.dup - 19284;
if (x <> 0) and (x <> 1) and (x <> $100) and (x <> $101)
then ktERRNO := 3
else begin
KT^.dup := x and 1;
if KT^.dup <> 0 then KT^.dup := 2*SizeOf(longint);
if KT^.inxct <= indexno then ktERRNO := 4
else begin
GetMem(KT^.keys,KT^.curinx);
if KT^.keys = nil then ktERRNO := 7
else begin KT^.ksz := KT^.curinx;
kt_read_data(KT^.keys^,KT^.curinx);
kt_next_index(indexno);
KT^.access := mode;
KT^.inx_entry := 0;
KT^.recptr := 0;
KT^.BaseEntry := 0;
KT^.start :=
kt_inx_size[KT^.keys^[3*(KT^.inxct-1) + 1]]*SizeOf(longint) +
KT^.keys^[3*KT^.inxct - 3] + 3;
set_min_size;
ktOpen := y + 1;
exit;
end;
end;
end;
end;
Close(KT^.fd);
end;
FreeMem(my_list^[y],SizeOf(kt_rec));
my_list^[y] := nil;
end;
function ktChangeIndex(f, indexno : integer) : Boolean;
begin ktChangeIndex := False;
if not kt_FileOpen(f) then exit;
if (indexno < 0) or (indexno >= KT^.inxct) then begin ktERRNO := 4;
exit;
end;
if indexno <> KT^.curinx then
begin kt_next_index(indexno);
KT^.BaseEntry := 0;
KT^.inx_entry := 0;
KT^.inx_pos := -KT^.keys^[3*KT^.curinx];
end;
ktChangeIndex := True;
end;
function ktFlush(f : integer) : Boolean;
begin ktFlush := False;
if not kt_FileOpen(f) then exit;
Close(KT^.fd);
Assign(KT^.fd,KT^.filename);
Reset(KT^.fd,1);
ktFlush := True;
end;
function ktClose(f : integer) : Boolean;
var y : integer;
begin if not kt_FileOpen(f) then ktClose := False
else begin Close(KT^.fd);
cur_ind_fd := 1000;
FreeMem(KT^.keys,KT^.ksz);
FreeMem(my_list^[f-1],SizeOf(kt_rec));
my_list^[f-1] := nil;
ktClose := True;
end;
end;
procedure add_indexes(var recpt);
var k,y : integer;
begin
k := KT^.curinx;
for y := 0 to KT^.inxct-1 do
if y <> k then begin kt_next_index(y);
kt_update_index(recpt,0);
end;
kt_next_index(k);
kt_update_index(recpt,0);
end;
function ktAdd(f : integer; var data; size : integer) : Boolean;
var areapt : charp; x,y : integer;
begin ktAdd := True;
if size < 1 then ktERRNO := 15
else if kt_FileOpen(f) then
begin if kt_OKtowrite then
begin
if size < KT^.minsiz then
begin GetMem(areapt,KT^.minsiz);
FillChar(areapt^,KT^.minsiz,#0);
Move(Chars(data),areapt^,size);
if size > KT^.hks then x := size
else x := KT^.hks;
if areapt^[x-1] <> #0 then Inc(x);
end
else areapt := nil;
if kt_OKtoadd(data,40) then
begin
KT^.recptr := KT^.fsize;
KT^.chain[0] := 0;
KT^.chain[1] := 0;
KT^.status := 0;
if areapt <> nil then
begin kt_wrt_elem(areapt^,x);
add_indexes(areapt^);
FreeMem(areapt,KT^.minsiz);
end
else
begin kt_wrt_elem(data,size);
add_indexes(data);
end;
exit;
end
else if areapt <> nil then
FreeMem(areapt,KT^.minsiz);
KT^.recptr := 0;
end;
end;
ktAdd := False;
end;
function ktAddPhys(f : integer; var data; size : integer) : Boolean;
begin if size < 1 then ktERRNO := 15
else if kt_FileOpen(f) then
if kt_OKtowrite then
begin KT^.chain[0] := 0;
KT^.chain[1] := 0;
KT^.recptr := KT^.fsize;
KT^.status := 2;
kt_wrt_elem(data,size);
ktAddPhys := True;
exit;
end;
ktAddPhys := False;
end;
function NN_NN(var recpt; b, errs : integer) : integer;
var a1 : integer; y,z,a2,comp,c2 : longint; q : Boolean;
begin
a1 := KT^.inx_entry;
a2 := KT^.inx_pos;
KT^.del := 0;
kt_read_index;
if (b <> 0) then comp := -KT^.keys^[3*KT^.curinx]
else comp := KT^.base;
while True do
begin if kt_FORWARD <= 0 then begin Dec(KT^.inx_entry);
q := (KT^.inx_entry <= 0) or
((b = 0) and (KT^.inx_pos = KT^.base) and
(KT^.inx_entry <> KT^.BaseEntry));
end
else begin Inc(KT^.inx_entry);
q := (KT^.inx_entry >= kt_inx_size[KT^.curtyp]) or
((b = 0) and (KT^.inx_pos = KT^.base) and
(KT^.inx_entry <> KT^.BaseEntry));
end;
if q then begin if KT^.inx_pos >= comp then
begin ktERRNO := errs;
KT^.inx_entry := a1;
KT^.inx_pos := a2;
NN_NN := 0;
exit;
end;
y := KT^.inx_pos;
KT^.inx_pos := kt_inx[0];
kt_read_index;
KT^.inx_entry := 1;
while y <> kt_inx[KT^.inx_entry] do
Inc(KT^.inx_entry);
end
else begin z := kt_inx[KT^.inx_entry];
if z > 0 then begin KT^.recptr := z;
NN_NN := kt_read_indexed(recpt);
exit;
end;
if z < 0 then begin
KT^.inx_pos := z;
kt_read_index;
if kt_FORWARD > 0 then KT^.inx_entry := 0
else KT^.inx_entry := kt_inx_size[KT^.curtyp];
end;
end;
end;
end;
function ktFind(fno : integer;var recpt; key : string) : integer;
var x,y : integer; temk : pointer;
begin ktFind := 0;
if not kt_FileOpen(fno) then exit;
ktERRNO := 0;
KT^.BaseEntry := 0;
if kt_lookup(key) then
begin y := kt_read_indexed(recpt);
if y = 0 then exit;
GetMem(oldk,KT^.maxkey+1);
if oldk = nil then begin ktERRNO := 7;
exit;
end;
kt_setupkey(oldk^,recpt);
x := kt_keysmatch(key,oldk^);
FreeMem(oldk,KT^.maxkey+1);
if (x = 0) or
((kt_FORWARD > 0) and (x < 0)) or
((kt_FORWARD < 0) and (x > 0)) then
begin ktFind := y;
exit;
end;
end;
if kt_FORWARD = 0 then begin ktERRNO := 17;
y := 0;
end
else begin if kt_FORWARD > 0 then x := 26
else x := 27;
y := NN_NN(recpt,1,x);
end;
ktFind := y;
end;
function ktRead(f : integer; var data; key : string) : integer;
begin kt_FORWARD := 0;
ktRead := ktFind(f,data,key);
end;
function ktReadAfter(f : integer; var data; key : string) : integer;
begin kt_FORWARD := 1;
ktReadAfter := ktFind(f,data,key);
end;
function ktReadBefore(f : integer; var data; key : string) : integer;
begin kt_FORWARD := -1;
ktReadBefore := ktFind(f,data,key);
end;
function ktLength(f : integer; key : string) : integer;
var x : integer; temk : pointer;
begin x := 0;
if kt_FileOpen(f) then
begin x := kt_exists(key);
if x = 0 then ktERRNO := 17;
end;
ktLength := x;
end;
function kt_goon(fno : integer;var recpt ; s : integer) : integer;
begin kt_goon := 0;
if not kt_FileOpen(fno) then exit;
if s = 0 then KT^.recptr := 0;
if KT^.recptr <= 0 then begin KT^.inx_pos := -KT^.keys^[3*KT^.curinx];
KT^.inx_entry := 0;
end
else if KT^.del = 2 then Dec(KT^.inx_entry);
kt_FORWARD := 1;
KT^.BaseEntry := 0;
kt_goon := NN_NN(recpt,1,26);
end;
function ktNext(f : integer; var data) : integer;
begin ktNext := kt_goon(f,data,1);
end;
function kt_goback(fno : integer; var recpt; s : integer) : integer;
begin kt_goback := 0;
if not kt_FileOpen(fno) then exit;
if s = 0 then KT^.recptr := 0;
if KT^.recptr <= 0 then begin
KT^.inx_pos := -KT^.keys^[3*KT^.curinx];
KT^.inx_entry := kt_inx_size[KT^.curtyp];
end
else if KT^.del = 1 then Inc(KT^.inx_entry);
kt_FORWARD := 0;
KT^.BaseEntry := 0;
kt_goback := NN_NN(recpt,1,27);
end;
function ktPrev(f : integer; var data) : integer;
begin ktPrev := kt_goback(f,data,1);
end;
procedure del_undel(a : byte);
var q,r,s,t : longint; r1 : array[0..11] of longint; b : byte;
begin r := KT^.chain[0];
s := r;
q := KT^.chain[1];
r1[1] := q;
t := q;
if a = 2 then begin t := KT^.recptr;
s := t;
end;
b := KT^.status;
kt_wrt_status;
if KT^.dup <> 0 then
begin if r = 0 then
begin KT^.status := a;
while r1[1] <> 0 do
begin kt_seek(r1[1]);
kt_wrt_data(KT^.status,1);
kt_read_data(r1[0],2*SizeOf(longint));
end;
KT^.status := b;
end
else begin
kt_seek(r + 1 + SizeOf(longint));
kt_wrt_data(t,SizeOf(longint));
if q <> 0 then
begin Inc(q);
kt_seek(q);
kt_wrt_data(s,SizeOf(longint));
end;
end;
end;
end;
function ktDelete(f : integer; var data) : Boolean;
var x,k : integer; temk : pointer;
begin if kt_locked(f) then begin ktDelete := False;
exit;
end;
KT^.status := KT^.status or $80;
del_undel($82);
if (KT^.status and 2) = 0 then
begin k := KT^.curinx;
if KT^.inxct > 1 then
begin for x := 0 to KT^.inxct - 1 do
if x <> k then
begin kt_next_index(x);
kt_record_lookup(data);
kt_zero_index(x);
end;
kt_next_index(k);
end;
kt_record_lookup(data);
kt_zero_index(k);
end;
ktDelete := True;
end;
function ktUndelete(f : integer; var data) : Boolean;
begin ktUndelete := False;
if not kt_FileOpen(f) or not kt_OKtowrite then exit;
if KT^.recptr <= 0 then begin ktERRNO := 20;
exit;
end;
if (KT^.status and $80) = 0 then begin ktERRNO := 29;
exit;
end;
if (KT^.status and 2) = 0 then
begin if not kt_OKtoadd(data,50) then exit;
add_indexes(data);
end;
KT^.status := KT^.status and $7f;
del_undel(2);
ktUndelete := True;
end;
procedure kt_alter_index(y : integer; var recpt);
begin kt_next_index(y);
KT^.inx_pos := oldix[y].ix;
KT^.inx_entry := oldix[y].en;
if KT^.inx_pos <> 0 then
begin kt_read_index;
if kt_alter[y].ix <> 0 then
begin KT^.inx_entry := oldix[y].en;
kt_zero_index(y);
kt_update_index(recpt,1);
end
else if record_moved then
begin kt_inx[KT^.inx_entry] := KT^.recptr;
kt_wrt_index;
end;
end;
end;
function ktRewrite(f : integer; var data; size : integer) : Boolean;
var x,y,z,i,j,k,e,ff : integer; keypt,oldrec : pointer;
areapt : charp; q,r,s,start : longint;
begin ktRewrite := False;
if size < 1 then begin ktERRNO := 15;
exit;
end;
if kt_locked(f) then exit;
if (size < KT^.minsiz) and (KT^.status and 2 = 0) then
begin GetMem(areapt,KT^.minsiz);
FillChar(areapt^,KT^.minsiz,#0);
Move(Chars(data),areapt^,size);
if size < KT^.hks then size := KT^.hks;
if areapt^[size-1] <> #0 then Inc(size);
end
else areapt := nil;
q := KT^.recptr;
r := KT^.inx_pos;
e := KT^.inx_entry;
k := KT^.curinx;
start := q + KT^.dup + 1;
kt_seek(start);
kt_read_data(old_length,4);
record_moved := (size > old_length[0] + old_length[1]);
if (KT^.status and 2) = 0 then
begin kt_inx_char := q;
z := 1;
if old_length[0] > KT^.maxkey then ff := old_length[0]
else ff := KT^.maxkey+1;
GetMem(oldrec,ff);
FillChar(oldrec^,ff,#0);
if oldrec = nil then
begin ktERRNO := 7;
if areapt <> nil then FreeMem(areapt,KT^.minsiz);
exit;
end;
kt_read_data(oldrec^,old_length[0]);
for y := KT^.inxct - 1 downto 0 do
begin kt_next_index(y);
x := 0;
GetMem(keypt,KT^.maxkey+1);
if keypt = nil then
begin ktERRNO := 7;
FreeMem(oldrec,ff);
if areapt <> nil then
FreeMem(areapt,KT^.minsiz);
exit;
end;
if areapt <> nil then
kt_setupkey(keypt^,areapt^)
else kt_setupkey(keypt^,Chars(data));
GetMem(oldk,KT^.maxkey+1);
if oldk = nil then
begin ktERRNO := 7;
FreeMem(keypt,KT^.maxkey+1);
FreeMem(oldrec,ff);
if areapt <> nil
then FreeMem(areapt,KT^.minsiz);
exit;
end;
kt_setupkey(oldk^,oldrec^);
kt_alter[y].ix := 0;
oldix[y].ix := 0;
if kt_keysmatch(oldk^,keypt^) <> 0 then
x := kt_exists(keypt^);
if (x = 0) and ((record_moved) or (kt_alter[y].ix <> 0)) then
begin
KT^.inx_pos := -KT^.keys^[3*KT^.curinx];
for j := 1 to KT^.maxkey do
begin kt_read_index;
i := kt_inx_key(Chars(oldk^)[j]);
if kt_inx[i] = 0 then
j := KT^.maxkey
else begin
kt_inx_char := kt_inx[i];
if kt_inx_char > 0 then
begin KT^.recptr := kt_inx_char;
j := KT^.maxkey
end
else KT^.inx_pos := kt_inx_char;
end;
end;
oldix[KT^.curinx].ix := KT^.inx_pos;
oldix[KT^.curinx].en := i;
end;
FreeMem(oldk,KT^.maxkey+1);
FreeMem(keypt,KT^.maxkey+1);
if x <> 0 then begin ktERRNO := 30 + y;
z := 0;
y := 0;
end;
end;
kt_next_index(k);
FreeMem(oldrec,ff);
KT^.recptr := q;
KT^.inx_pos := r;
KT^.inx_entry := e;
if z = 0 then
begin if areapt <> nil then FreeMem(areapt,KT^.minsiz);
exit;
end;
end;
if record_moved then
begin KT^.recptr := q;
KT^.status := KT^.status or $80;
kt_wrt_status;
KT^.recptr := KT^.fsize;
s := KT^.recptr;
KT^.status := KT^.status and $7f;
if areapt <> nil then
kt_wrt_elem(areapt^,size)
else kt_wrt_elem(Chars(data),size);
if KT^.dup <> 0 then
begin if KT^.chain[0] <> 0 then
begin kt_seek(KT^.chain[0] + 1 + SizeOf(longint));
kt_wrt_data(s,SizeOf(longint));
end;
if KT^.chain[1] <> 0 then
begin kt_seek(KT^.chain[1] + 1);
kt_wrt_data(s,SizeOf(longint));
end;
end;
end
else begin if size <> old_length[0] then
begin Inc(old_length[1],old_length[0] - size);
old_length[0] := size;
kt_seek(start);
kt_wrt_data(old_length,4);
end
else kt_seek(start + 4);
if areapt <> nil then
kt_wrt_data(areapt^,size)
else kt_wrt_data(Chars(data),size);
end;
if (KT^.status and 2) = 0 then
if areapt <> nil then
begin for y := 0 to KT^.inxct- 1 do
if y <> k then kt_alter_index(y,areapt^);
kt_alter_index(k,areapt^);
end
else
begin for y := 0 to KT^.inxct- 1 do
if y <> k then kt_alter_index(y,Chars(data));
kt_alter_index(k,Chars(data));
end;
if areapt <> nil then FreeMem(areapt,KT^.minsiz);
ktRewrite := True;
end;
procedure ktGetChar;
var d : integer; Regs : registers;
begin if (ktRUNCH <> char(0)) or (ktRUNSC <> 0) then
begin ktCHAR := ktRUNCH;
ktSCAN := ktRUNSC;
ktRUNCH := char(0);
ktRUNSC := 0;
end
else while True do
begin Regs.ax := 0;
intr($16,Regs);
ktSCAN := integer(regs.ah);
ktCHAR := char(regs.al);
if (ktSCAN < 59) or (ktSCAN > 68) or (kt_function)
then exit;
ktFKEY := ktSCAN - 58;
kt_function := True;
ktProcessFunctionKey;
kt_function := False;
end;
end;
procedure ktGetPress;
begin ktGetChar;
ktRUNCH := ktCHAR;
ktRUNSC := ktSCAN;
end;
function ktGetStr(var data ; maxlen : integer) : integer;
var x,z : integer;
begin if maxlen = 0 then maxlen := -1;
x := 1;
z := 0;
while (z = 0) do
begin ktGetChar;
if (ktSCAN = 1) or (ktSCAN = 28) then z := 1
else begin if (ktSCAN = 14) then
begin if x > 1 then begin Dec(x);
Chars(data)[x] := #0;
ktBackSpace;
end;
end
else begin if (ktCHAR = #0) then
begin if (ktSCAN = 75) and (x > 0) then
begin ktPutChar(#8);
Dec(x);
end else if (ktSCAN = 77) and
(x < maxlen) then
begin if Chars(data)[x] < #32 then
Chars(data)[x] := ' ';
ktPutChar(Chars(data)[x]);
Inc(x);
end;
end
else begin if x >= maxlen then z := 1
else if ktCHAR > #31 then
begin Chars(data)[x] := ktCHAR;
Inc(x);
ktPutChar(ktCHAR);
end;
end;
end;
end;
end;
ktGetStr := x;
Dec(x);
Chars(data)[0] := char(x);
end;
function get_next_part(k : integer; var recpt, keypt) : integer;
var x,y,z,L : integer; q : longint;
begin L := KT^.keys^[KT^.ixdes + 2*k];
y := 1;
for x := ktCT to ktCT + L - 1 do Chars(keypt)[x] := #0;
get_next_part := 0;
for x := 1 to L do
begin ktGetChar;
if (ktSCAN = 14) or
((ktCHAR = #0) and (ktSCAN = 75)) then
begin if ktCT > 1 then
begin Dec(ktCT);
Chars(keypt)[ktCT] := #0;
Dec(Chars(keypt)[0]);
ktBackSpace;
if ktCT = 1 then
KT^.inx_pos := -KT^.keys^[3*KT^.curinx]
else begin KT^.inx_pos := q;
kt_read_index;
q := kt_inx[0];
end;
end;
end
else begin if ktSCAN = 1 then exit;
if ktSCAN = 28 then ktCHAR := #0
else if ktCHAR > #31 then ktPutChar(ktCHAR);
Chars(keypt)[ktCT] := ktCHAR;
Inc(Chars(keypt)[0]);
Inc(ktCT);
kt_read_index;
z := kt_inx_key(ktCHAR);
kt_inx_char := kt_inx[z];
if kt_inx_char > 0 then
begin KT^.recptr := kt_inx_char;
get_next_part :=
kt_read_indexed(recpt);
kt_found := True;
exit;
end;
if kt_inx_char = 0 then
begin if ktCHAR = #0 then get_next_part := -1;
exit;
end;
q := KT^.inx_pos;
KT^.inx_pos := kt_inx_char;
if ktCHAR = #0 then begin get_next_part := 1;
exit;
end;
end;
end;
get_next_part := y;
end;
function ktGetKey(f : integer; var data,key) : integer;
var y,k : integer;
begin if not kt_FileOpen(f) then y := 0
else begin
KT^.inx_pos := -KT^.keys^[3*KT^.curinx];
KT^.del := 0;
KT^.BaseEntry := 0;
KT^.recptr := 0;
Chars(key)[0] := #0;
ktCT := 1;
for k := 0 to KT^.keys^[3*KT^.curinx + 2] - 1 do
begin kt_found := False;
y := get_next_part(k,data,key);
if (kt_found) or (y <= 0) then
begin ktGetKey := y;
if ktCHAR = #0 then Dec(Chars(key)[0]);
exit;
end;
ktSeparator;
end;
end;
ktGetKey := y;
end;
function ktReadAll(f : integer; var data; key : string) : integer;
var x,y,z,ff : integer; okey : pointer;
begin ktReadAll := 0;
if not kt_FileOpen(f) then exit;
KT^.inx_pos := -KT^.keys^[3*KT^.curinx];
KT^.BaseEntry := 1;
KT^.base := -1;
y := integer(key[0]);
if y > KT^.maxkey then y := KT^.maxkey;
for x := 1 to y do
begin KT^.base := KT^.inx_pos;
kt_read_index;
z := kt_inx_key(key[x]);
if kt_inx[z] = 0 then begin KT^.BaseEntry := 0;
ktERRNO := 17;
exit;
end;
KT^.inx_entry := z;
KT^.BaseEntry := KT^.inx_entry;
kt_inx_char := kt_inx[z];
if kt_inx_char > 0 then
begin KT^.recptr := kt_inx_char;
z := kt_read_indexed(data);
if z <> 0 then
begin ff := KT^.maxkey+1;
GetMem(okey,ff);
if (okey = nil) then exit;
kt_setupkey(okey^,data);
while (x <= y) do
begin if kt_inx_key(key[x]) <>
kt_inx_key(Chars(okey^)[x]) then
begin KT^.BaseEntry := 0;
z := 0;
ktERRNO := 17;
x := y + 1;
end
else Inc(x);
end;
FreeMem(okey,ff);
ktReadAll := z;
exit;
end;
end;
KT^.inx_pos := kt_inx_char;
end;
KT^.inx_entry := 0;
kt_FORWARD := 1;
ktReadAll := NN_NN(data,0,0);
end;
function ktFileBase(var recpt; fno : integer) : integer;
begin if kt_FileOpen(fno) then
begin if (KT^.BaseEntry <> 0) and (KT^.base < 0) then
begin if (KT^.del <> 0) and ((KT^.base > KT^.inx_pos) or
(KT^.inx_entry = KT^.BaseEntry))
then begin if kt_FORWARD <> 0 then
begin if KT^.del = 2 then Dec(KT^.inx_entry);
end
else
begin if KT^.del = 1 then Inc(KT^.inx_entry);
end;
end;
ktFileBase := NN_NN(recpt,0,0);
exit;
end
else begin if KT^.BaseEntry <> 0 then ktERRNO := 0
else ktERRNO := 25;
end;
end;
ktFileBase := 0;
end;
function ktNextAll(f : integer; var data) : integer;
begin kt_FORWARD := 1;
ktNextAll := ktFileBase(data,f);
end;
function ktPrevAll(f : integer; var data) : integer;
begin kt_FORWARD := 0;
ktPrevAll := ktFileBase(data,f);
end;
function ktAddChain(f : integer; var data; size : integer) : Boolean;
var q,r : longint;
begin ktAddChain := False;
if kt_FileReady(f) then
begin if KT^.dup = 0 then ktERRNO := 23
else if kt_OKtowrite then
begin if size < 1 then ktERRNO := 15
else begin q := KT^.fsize;
kt_seek(KT^.recptr + 1 + SizeOf(longint));
kt_wrt_data(q,SizeOf(longint));
r := KT^.chain[1];
if r <> 0 then begin Inc(r);
kt_seek(r);
kt_wrt_data(q,SizeOf(longint));
end;
KT^.chain[0] := KT^.recptr;
KT^.recptr := q;
KT^.status := 2;
kt_wrt_elem(data,size);
ktAddChain := True;
end;
end;
end;
end;
function NN_Chain(var recpt; fno, n : integer) : integer;
var q : longint; x : integer;
begin
NN_Chain := 0;
if kt_FileOpen(fno) then
begin if KT^.dup = 0 then ktERRNO := 23 else
begin if KT^.recptr <= 0 then ktERRNO := 20 else
begin x := KT^.status and $80;
if (x <> 0) and (KT^.chain[0] = 0) then
ktERRNO := 28 else
begin q := KT^.chain[n];
if q <> 0 then
begin KT^.recptr := q;
kt_seek(q);
kt_read_data(KT^.status,1);
NN_Chain := kt_read_elem(recpt);
end;
end;
end;
end;
end;
end;
function ktNextChain(f : integer; var data) : integer;
begin ktNextChain := NN_Chain(data,f,1);
end;
function ktPrevChain(f : integer; var data) : integer;
begin ktPrevChain := NN_Chain(data,f,0);
end;
function ktStart(f : integer; var data) : integer;
begin ktStart := kt_goon(f,data,0);
end;
function ktEnd(f : integer; var data) : integer;
begin ktEnd := kt_goback(f,data,0);
end;
function record_status : Boolean;
begin kt_seek(KT^.recptr);
kt_read_data(KT^.status,1);
ktINDEXED := ( (KT^.status and 2) = 0);
record_status := ((KT^.status < byte('0')) or (KT^.status > byte('9')));
end;
function kt_goonPhys(fno : integer; var recpt;s : integer) : integer;
var y : integer; b : byte;
begin kt_goonPhys := 0;
if not kt_FileOpen(fno) then exit;
if s = 0 then KT^.recptr := 0;
if KT^.recptr <= 0 then KT^.recptr := KT^.start
else KT^.recptr := KT^.nexrec;
while True do
begin if KT^.recptr >= KT^.fsize then
begin ktERRNO := 19;
exit;
end;
if record_status then
begin y := kt_read_elem(recpt);
if (KT^.status and $80) <> 0 then y := -y;
kt_goonPhys := y;
exit;
end;
b := KT^.status - 48;
Inc(KT^.recptr, 3 + kt_inx_size[KT^.keys^[3*b + 1]]*SizeOf(longint));
end;
end;
function ktNextPhys(f : integer; var data) : integer;
begin ktNextPhys := kt_goonPhys(f,data,1);
end;
function kt_gobackPhys(var recpt; fno, s : integer) : integer;
var z : integer;
begin kt_gobackPhys := 0;
if not kt_FileOpen(fno) then exit;
if s = 0 then KT^.recptr := 0;
if KT^.recptr <= 0 then KT^.recptr := KT^.fsize;
while True do
begin if KT^.recptr <= KT^.start then begin ktERRNO := 21;
exit;
end;
kt_seek(KT^.recptr - 2);
kt_read_data(z,2);
Dec(KT^.recptr,z);
if record_status then
begin z := kt_read_elem(recpt);
if (KT^.status and $80) <> 0 then z := -z;
kt_gobackPhys := z;
exit;
end;
end;
end;
function ktPrevPhys(f : integer; var data) : integer;
begin ktPrevPhys := kt_gobackPhys(data,f,1);
end;
function ktStartPhys(f : integer; var data) : integer;
begin ktStartPhys := kt_goonPhys(f,data,0);
end;
function ktEndPhys(f : integer; var data) : integer;
begin ktEndPhys := kt_gobackPhys(data,f,0);
end;
function FirstChar(y, f : integer) : Boolean;
begin FirstChar := False;
if not kt_FileReady(f) then exit;
if (KT^.status and $80) <> 0 then begin ktERRNO := 28;
exit;
end;
KT^.status := (KT^.status and 254) or y;
kt_wrt_status;
FirstChar := ktFlush(f);
end;
function ktLock(f : integer) : Boolean;
begin ktLock := FirstChar(1,f);
end;
function ktUnlock(f : integer) : Boolean;
begin ktUnlock := FirstChar(0,f);
end;
function ktLocked(f : integer; key : string) : Boolean;
begin ktLocked := False;
if not kt_FileOpen(f) then exit;
if kt_exists(key) = 0 then begin ktERRNO := 17;
ktLocked := False;
end
else ktLocked := ((KT^.status and 1) <> 0);
end;
function ktSize(f : integer) : longint;
begin if not kt_FileOpen(f) then ktSize := 0
else ktSize := KT^.fsize;
end;
function ktRecords(f,typ : integer) : longint;
var x,l : longint; b,c : byte; a : array[0..7] of char;
begin
if not kt_FileOpen(f) then begin ktRecords := 0;
exit;
end;
l := KT^.start;
x := 0;
while (l < KT^.fsize) do
begin kt_seek(l);
kt_read_data(a,1);
if (a[0] >= '0') and (a[0] <= '9') then
Inc(l, kt_inx_size[KT^.keys^[3*(byte(a[0])-48) + 1]]*SizeOf(longint)
+ 3)
else begin b := byte(a[0]) and $80;
if (typ = 0) or
((typ > 0) and (b = 0)) or
((typ < 0) and (b <> 0)) then Inc(x);
if KT^.dup <> 0 then kt_read_data(a,KT^.dup);
kt_read_data(kt_tmplen[0],2);
kt_read_data(kt_tmplen[1],2);
Inc(l, 7 + KT^.dup + kt_tmplen[0] + kt_tmplen[1]);
end;
end;
ktRecords := x;
end;
function ktMaxRead(f,max : integer) : integer;
begin ktMaxRead := 0;
if kt_FileOpen(f) then
begin if (max < 0) or ((max > 0) and (max < KT^.minsiz)) then
ktERRNO := 15
else begin KT^.maxread := max;
ktMaxRead := KT^.minsiz;
end;
end;
end;
procedure KtBuildKey(f : integer; var d ;f1,f2 : string);
var x,y,m1,m2 : integer;
type chars = array[0..1] of char;
begin if not kt_FileOpen(f) then exit;
y := 3*KT^.inxct;
for x := 0 to KT^.curinx - 1 do Inc(y,2*KT^.keys^[3*x + 2]);
m1 := KT^.keys^[y];
m2 := KT^.keys^[y + 2];
x := m1 + m2;
FillChar(d,x + 1, #0);
x := length(f1);
if x > m1 then x := m1;
Move(f1[1],chars(d)[1],x);
if x < m1 then Inc(x);
y := length(f2);
if y > m2 then y := m2;
Move(f2[1],chars(d)[1 + x],y);
if y < m2 then Inc(y);
chars(d)[0] := char(x + y);
end;
{$I+}
end.